#! _*_ coding: utf8 _*_
from django.contrib.auth.models import User
from django.shortcuts import render
from rest_framework.decorators import api_view

from teacher.models import Teacher
from school.models import School
from teacher.serializers import TeacherSeri
from tools.err import RoingException, ErrorDoesNotExist
from .models import Student, SClass, SComment, STextBook
from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
from django.core import serializers
from accounts.util import create_user, params_of_request
from student.serializers import StudentSerializer, SCommentSerializer, TextBookSeri, SClassSerializer
from rest_framework.renderers import JSONRenderer
import json
import datetime


# Create your views here.

def students(teacher_id):
    teachers = Teacher.objects.filter(teacher=teacher_id)
    return teachers


def student(request):
    pass


def delete_student(request):
    student_id = request.POST.get('student_id', 0)
    teacher_id = request.POST.get('teacher_id', 0)
    try:
        student = Student.objects.get(pk=student_id)
        teacher = Teacher.objects.get(pk=teacher_id)
        teacher.students.remove(student)
        teacher.save()
    except Exception as e:
        return JsonResponse({'msg': str(e)})

    return JsonResponse({'msg': 'success'})


@api_view(['POST'])
def delete_class(request):
    params = request.data.get('class', {})
    pk = params.get('pk', None)
    if not pk:
        raise RoingException(message=u'无效的课程', code=603)
    else:
        try:
            clz = SClass.objects.get(pk=int(pk))
            clz.delete()
        except Exception as e:
            raise RoingException(message=u'课程不存在', code=604)
        return JsonResponse({'class': params})


def del_from_class(request):
    params = params_of_request(request)
    stu_pk = params.get('student', None)
    clz_pk = params.get('class', None)
    try:
        stu = Student.objects.get(pk=int(stu_pk))
        clz = SClass.objects.get(pk=int(clz_pk))

        stu.classes.remove(clz)
        if not len(clz.class_students.all()):
            ''' 如果没有一个学生，删除该课程 '''
            clz.delete()

        return JsonResponse({'student': StudentSerializer(stu).data}, safe=False)
    except Exception as e:
        return JsonResponse({'err': 2, 'msg': u'无效的课程或学生'})


def add_to_class(request):
    params = params_of_request(request)

    stu_pk = params.get('student', None)
    clz_pk = params.get('class', None)
    try:
        stu = Student.objects.get(pk=int(stu_pk))
        clz = SClass.objects.get(pk=int(clz_pk))

        stu.classes.add(clz)
        stu.save()

        return JsonResponse({'student': StudentSerializer(stu).data}, safe=False)
    except Exception as e:
        return JsonResponse({'err': 2, 'msg': u'无效的课程或学生'})


def update_class(request):
    class_id = request.POST.get('class_id', -1)

    response = {}
    try:
        clz = SClass.objects.get(pk=class_id)
        begin_str = request.POST['begin']
        duration_str = request.POST['duration']
        weekday = request.POST['weekday']

        begin = datetime.datetime.strptime(begin_str, '%H:%M')
        duration = datetime.timedelta(0, float(duration_str) * 3600)

        clz.begin = begin
        clz.duration = duration
        clz.weekday = int(weekday)
        clz.save()
    except Exception as e:
        return HttpResponse(str(e))
    return HttpResponse('Success')


def add_student(request):
    if request.method == 'GET':
        return render(request, 'student-add.html',
                      {'user': request.user, 'school_id': request.GET.get('school_id', None)})
    else:
        user = create_user(None, request.POST, {})
        if not user:
            return JsonResponse({'msg': 'error'})

        try:
            student = Student.objects.get(me=user)
        except Exception as e:
            student = Student.objects.create(me=user)

        school_id = request.POST.get('school_id', None)
        try:
            school = School.objects.get(pk=school_id)
            school.students.add(student)
            student.save()
            school.save()
            return HttpResponseRedirect('/students/add?school_id=' + str(school_id))
        except Exception as e:
            return JsonResponse({'msg': str(e)})


def c_add_student(request):
    params = params_of_request(request)
    user = create_user(None, params, {})
    if not user:
        return JsonResponse({'msg': 'error'})

    try:
        student = Student.objects.get(me=user)
    except Exception as e:
        student = Student.objects.create(me=user)

    school_id = params.get('school_id', None)
    try:
        school = School.objects.get(pk=school_id)
        school.students.add(student)
        student.save()
        school.save()
        return JsonResponse({'student': StudentSerializer(student).data})
    except Exception as e:
        return JsonResponse({'msg': str(e)})


def add_comment(request):
    teacher_id = request.POST.get('teacher_id', -1)
    student_id = request.POST.get('student_id', -1)
    response = {}

    try:
        teacher = Teacher.objects.get(pk=teacher_id)
        student = Student.objects.get(pk=student_id)

        score = request.POST['score']
        textbook = request.POST['textbook']
        content = request.POST['content']

        textbook = STextBook.objects.get(pk=int(textbook))
        scomment = SComment.objects.create(score=int(score), textbook=textbook, content=content)
        scomment.save()
        student.comments.add(scomment)
        student.save()
    except Exception as e:
        return HttpResponse(e)
    return HttpResponse('Success')


def textbook(request):
    textbooks = STextBook.objects.all()
    return JsonResponse(TextBookSeri(textbooks, many=True).data, safe=False)


@api_view(['POST', 'GET'])
def c_class_add_textbook(request):
    params = request.data
    klass_json = params.get('class', {})
    textbook_json = params.get('textbook', {})
    try:
        klass = SClass.objects.get(pk=klass_json['pk'])
        textbook = STextBook.objects.get(pk=int(textbook_json['pk']))
        klass.textbooks.add(textbook)
        klass.save()
    except Exception as e:
        raise RoingException(code=601, message=u"无效的课程或教材")

    return JsonResponse(SClassSerializer(data=klass), safe=False)


@api_view(['POST', 'GET'])
def c_class_update_textbooks(request):
    params = request.data
    klass_json = params.get('class', {})
    textbooks_json = params.get('textbooks', [])
    try:
        klass = SClass.objects.get(pk=klass_json['pk'])
        klass.textbooks.clear()
        for tb_json in textbooks_json:
            textbook = STextBook.objects.get(pk=int(tb_json['pk']))
            klass.textbooks.add(textbook)
        klass.save()
    except Exception as e:
        raise RoingException(code=601, message=u"无效的课程或教材")

    return JsonResponse(klass_json)


def c_add_comment(request):
    try:
        params = json.loads(request.body)
        student_json = params.get('student', {})
        s_id = student_json.get('pk', -1)
        student = Student.objects.get(pk=int(s_id))

        comments_json = params.get('comments', [])
        for c in comments_json:
            tb_name = c.get('textbook', '')
            tb = None
            try:
                tb = STextBook.objects.get(textbook=tb_name)
            except Exception as e:
                tb = STextBook.objects.create(textbook=tb_name)
            c['textbook'] = tb
            comment = SComment.objects.create(**c)
            comment.save()
            student.comments.add(comment)
            student.save()
    except Exception as e:
        return HttpResponse(status=601, content=str(e))
    return JsonResponse({'msg': 'success'})


def c_classes(request):
    try:
        student = Student.objects.get(me=request.user)
        return JsonResponse({'classes': SClassSerializer(student.classes.all(), many=True).data})
    except Exception as e:
        return JsonResponse({'msg': str(e)})
    return JsonResponse({'msg': 'error'})


def c_teachers(request):
    try:
        student_params = request.POST.get('student', {})
        student = None
        if student_params:
            s_pk = student_params.get('pk', None)
            if s_pk:
                student = Student.objects.get(pk=int(s_pk))
            else:
                me_pk = student_params.get('me', {}).get('pk', None)
                if me_pk and request.user.pk != int(me_pk):
                    u = User.objects.get(pk=int(me_pk))
                    student = Student.objects.get(me=u)
        if not student:
            student = Student.objects.get(me=request.user)
        return JsonResponse({'teachers': TeacherSeri(student.student_teachers.all(), many=True).data}, safe=False)
    except Exception as e:
        return JsonResponse({'code': 0, 'msg': str(e)})
    return JsonResponse({'code': 0, 'msg': 'unknown'})


@api_view(['GET', 'POST'])
def c_detail(request):
    params = request.data

    students = []
    try:
        for s in params.get('students', []):
            s_id = s.get('pk', None)
            student = {}
            if s_id:
                student = Student.objects.get(pk=int(s_id))
            else:
                student = Student.objects.get(me=request.user)
            students.append(student)
    except Exception as e:
        return JsonResponse({'msg': 'error'})
    return JsonResponse(StudentSerializer(students, many=True).data, safe=False)


@api_view(['POST', 'GET'])
def c_update_student_detail(request):
    try:
        json_students = request.data.get('students', [])
        json_out = []
        for json_student in json_students:
            json_student['me'].pop('userprofile')
            student = Student.objects.get(pk=int(json_student.get('pk', 0)))
            seri = StudentSerializer(student, data=json_student)
            seri.is_valid()
            seri.save()

            json_out.append(seri.data)

        return JsonResponse({'students': json_out}, safe=False)
    except Student.DoesNotExist as e:
        raise RoingException(message=str(e), code=ErrorDoesNotExist)
    except Exception as e:
        raise RoingException(message=str(e), code=603)
